#!/usr/bin/env python
"""
Acorn-SDR ('A Collection of Radio Nodes')
(c) Bob Cowdery (G3UKB) 2009

File: persist.py
Date: April 2009

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

The author can be reached by email at

bob@g3ukb.co.uk

================================================================================
Module Description:

The bootstrapper. This will query the profile to be used, aelect the profile and
load the required processes. It will then quietly go away.

"""
#-------------------------------------------------------------------------------
# System imports
import sys
import os
from os import kill
import signal
from time import sleep
import subprocess
import Ice, IceStorm

# Application imports
import gtk_bootstrap_gui as gui
import ice_helpers
import utils

# Import the Ice interface definitions
import AcornPersist
        
#===============================================================================
# The main class of the bootstrap GUI application
class AppBootstrapGui(Ice.Application):
  
    #---------------------------------------------------------------------------
    def __init__(self, home):
        self.HOME = home
            
    #---------------------------------------------------------------------------
    # Run the app
    def run(self, args):
       
        #-----------------------------------------------------------------------
        # Try to connect to the persist service as it may be running on another machine
        start_persist = False
        try:
            print 'Trying to connect to a persistence service...'
            persist = ice_helpers.get_interface('Bootstrap', self.communicator, AcornPersist.PersistPrx, 'Persist.Proxy')
            print 'Found a running service.'
        except:
            # Nope
            print 'No service found so starting a persistence service.'
            start_persist = True
        
        if start_persist:
            # In order to start the persist process we need to have some things in the directory tree fixed.
            # 1. 'ACORN_HOME/persistence' is where the persist scripts live
            # 2. The service is called persist_service.py
            # 2. ../conf/ice is the relative path from ACORN_HOME where the ice config lives
            # 3. The main config file is called acorn_ice.config
            # If persist is not running its a fair assumption that IceStorm isn't running either
            # We need to be in the right directory to start IceStorm
            os.chdir(HOME + '/../conf/ice')
            subprocess.Popen(['icebox', '--Ice.Config=config.icebox'])
            sleep(1)
            os.chdir(HOME)
            persist_proc = subprocess.Popen(['python', self.HOME + '/persistance/persist_service.py', args[1]])
        
            #-----------------------------------------------------------------------
            # Get the persist interface
            persist = ice_helpers.get_interface('Bootstrap', self.communicator, AcornPersist.PersistPrx, 'Persist.Proxy')
        
        # Get essential config data
        glade_path = utils.persist_get(persist, 'Profile', 'path.glade')
        
        #-----------------------------------------------------------------------
        # Initialise the GUI
        gui_impl = gui.BootstrapGui(glade_path, persist)
        
        #-----------------------------------------------------------------------
        print 'Acorn-SDR (Bootstrap) running..'
        
        # Start the GUI
        r = gui_impl.main()
        if r < 0:
            # Cancelled or some error occured
            # Kill whatever we started
            if start_persist:
                if persist_proc:
                    self.wait(persist_proc)
            subprocess.Popen(['killall', 'icebox'])
            return
        else:
            # Return when a selection has been made.
            # A profile has now been set. See what we need to start.
            # Does Jack need starting
            start_jack = utils.persist_get(persist, 'Profile', 'jack.load')
            if start_jack:
                fixed = utils.persist_get(persist, 'Profile', 'audio.outputfixed')
                periods = utils.persist_get(persist, 'Profile', 'jack.periods')
                if fixed:
                    # These are the fixed params for jack
                    rate = 48000
                    frames = 512
                else:
                    # Take it from the config
                    rate = utils.persist_get(persist, 'Profile', 'audio.rate')
                    frames = utils.persist_get(persist, 'Profile', 'audio.frames')
                subprocess.Popen(['jackd', '-dalsa', '-dhw:0', '-r' + str(rate), '-p' + str(frames), '-n' + str(periods)])
            # Now start the application processes    
            processes = utils.persist_get(persist, 'Profile', 'processes')
            process_list = processes.rsplit(',')
            for process in process_list:
                # Start each process
                path = utils.persist_get(persist, 'Profile', 'path.' + process)
                subprocess.Popen(['python', self.HOME + path, args[1]])
                sleep(1)
            
            # The bootstrap process now exits as it is not part of the running system
     
    #---------------------------------------------------------------------------           
    def wait(self, proc):
        pid = proc.pid
        kill(pid, signal.SIGKILL)
        # We must wait or it will get zombified
        proc.wait()
        
#===============================================================================
#===============================================================================
# Start from the command line
if __name__ == "__main__":
   
    # Get the persist service, can't do anything without it
    # First get the home directory for this system or fragment
    try:
        HOME = os.environ['ACORN_HOME']
    except:
        # Can't do much without that
        print 'Please set environment variable ACORN_HOME to point to the parent Acorn directory!'
        exit
        
    # Set our current directory
    os.chdir(HOME)
    
    app = AppBootstrapGui(HOME)
    app.main(sys.argv, sys.argv[1])
  
    # Announce we are going 
    print 'Acorn-SDR (Bootstrap) closing..'
  